package com.mini.mybatis.mybatisministep11.builder.xml;

import com.mini.mybatis.mybatisministep11.builder.BaseBuilder;
import com.mini.mybatis.mybatisministep11.io.Resources;
import com.mini.mybatis.mybatisministep11.builder.MapperBuilderAssistant;
import com.mini.mybatis.mybatisministep11.sqlsession.configuration.Configuration;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.util.List;

public class XmlMapperBuilder extends BaseBuilder {

    private Element element;

    private String resource;

    private MapperBuilderAssistant builderAssistant;


    public XmlMapperBuilder(InputStream inputStream, Configuration configuration, String resource) throws DocumentException {
        this(new SAXReader().read(inputStream),configuration,resource);
    }

    public XmlMapperBuilder(Document document, Configuration configuration, String resource) {
        super(configuration);
        this.builderAssistant = new MapperBuilderAssistant(configuration,resource);
        this.element = document.getRootElement();
        this.resource = resource;
    }


    public void parse() throws ClassNotFoundException {
        // 如果已经解析过则不需要再次解析
        if (!configuration.isResourceLoaded(resource)){
            // 解析当前xml，从根节点开始解析
            configurationElement(element);
            // 解析完成后，标记一下
            configuration.addLoadedResource(resource);
            // 绑定映射器注册器-namespace
            configuration.addMapper(Resources.classForName(builderAssistant.getCurrentNamespace()));
        }

    }

    private void configurationElement(Element element) {
        //1. 配置currentNameSpace
        String namespace = element.attributeValue("namespace");
        if (namespace.equals("")){
            throw new RuntimeException("Mapper's namespace cannot be empty");
        }
        builderAssistant.setCurrentNamespace(namespace);

        //2. select|update|insert|delete
        buildStatementFromContext(element.elements("select"),
                element.elements("insert"),
                element.elements("update"),
                element.elements("delete"));
    }

    private void buildStatementFromContext(List<Element>... elementLists) {
        for (List<Element> elementList : elementLists) {
            // 解析每一个sql标签
            for (Element element : elementList) {
                // 每一个标签都要创建一个XmlStatementBuilder去解析
                XmlStatementBuilder xmlStatementBuilder = new XmlStatementBuilder(configuration, builderAssistant, element);
                xmlStatementBuilder.parse();
            }
        }
    }
}
